package cn.wolfcode.cloud.shop.service.impl;

import cn.wolfcode.cloud.shop.consts.MQConstants;
import cn.wolfcode.cloud.shop.domain.OrderInfo;
import cn.wolfcode.cloud.shop.exception.BusinessException;
import cn.wolfcode.cloud.shop.mapper.OrderInfoMapper;
import cn.wolfcode.cloud.shop.redis.SeckillRedisKey;
import cn.wolfcode.cloud.shop.resp.SeckillServerCodeMsg;
import cn.wolfcode.cloud.shop.service.IOrderInfoService;
import cn.wolfcode.cloud.shop.service.ISeckillGoodService;
import cn.wolfcode.cloud.shop.service.ISeckillOrderService;
import cn.wolfcode.cloud.shop.util.IdGenerateUtil;
import cn.wolfcode.cloud.shop.vo.SeckillGoodsVo;
import org.apache.rocketmq.spring.core.RocketMQTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;

/**
 * @author Administrator
 */
@Service
public class OrderInfoServiceImpl implements IOrderInfoService {

    @Autowired
    private ISeckillGoodService seckillGoodService;

    @Autowired
    private ISeckillOrderService seckillOrderService;

    @Autowired
    private OrderInfoMapper orderInfoMapper;

    @Autowired
    private StringRedisTemplate redisTemplate;

    @Autowired
    private RocketMQTemplate rocketMQTemplate;


    @Override
    @Transactional(rollbackFor = Exception.class)
    public String doSeckill(Long seckillId, Long userId) {
        SeckillGoodsVo seckillGoodsVo = seckillGoodService.queryById(seckillId);
        return doSeckill(seckillGoodsVo, userId);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public String doSeckill(SeckillGoodsVo seckillGoodsVo, Long userId) {
        //1.扣减库存
        Integer ret = seckillGoodService.decrStockCount(seckillGoodsVo.getId());
        if(ret <= 0){
            throw new BusinessException(SeckillServerCodeMsg.OUT_OF_STOCK);
        }
        //2.创建基本订单
        String orderNo = this.createOrderInfo(seckillGoodsVo,userId);
        System.out.println(orderNo);
        //3.创建秒杀订单
        seckillOrderService.createSeckillOrder(orderNo,seckillGoodsVo.getId(),userId);
        //4.返回订单号
        return orderNo;
    }

    @Override
    public OrderInfo queryByOrderNo(String orderNo) {
        return orderInfoMapper.selectByOrderNo(orderNo);
    }


    private String createOrderInfo(SeckillGoodsVo seckillGoodsVo, Long userId) {
        OrderInfo orderInfo = new OrderInfo();
        orderInfo.setUserId(userId);
        orderInfo.setCreateDate(new Date());
        orderInfo.setStatus(OrderInfo.STATUS_ARREARAGE);
        orderInfo.setDeliveryAddrId(1L);
        orderInfo.setGoodCount(1);
        orderInfo.setGoodId(seckillGoodsVo.getGoodId());
        orderInfo.setGoodImg(seckillGoodsVo.getGoodImg());
        orderInfo.setGoodName(seckillGoodsVo.getGoodName());
        orderInfo.setGoodPrice(seckillGoodsVo.getGoodPrice());
        orderInfo.setSeckillPrice(seckillGoodsVo.getSeckillPrice());
        String orderNo = IdGenerateUtil.get().nextId()+"";
        orderInfo.setOrderNo(orderNo+"");
        //保存订单信息
        orderInfoMapper.insert(orderInfo);
        return orderNo;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void checkOrderTimeOut(String orderNo, Long userId, Long seckillId) {
        OrderInfo orderInfo = orderInfoMapper.selectByOrderNo(orderNo);
        if(orderInfo==null){
            return;
        }
        if(!OrderInfo.STATUS_ACCOUNT_PAID.equals(orderInfo.getStatus())){
            seckillGoodService.incrStockCount(seckillId);

            orderInfoMapper.updateStatusByOrderNo(orderNo,OrderInfo.STATUS_TIMEOUT);

            SeckillGoodsVo seckillGoodsVo = seckillGoodService.queryById(seckillId);

            redisTemplate.opsForHash().put(SeckillRedisKey.SECKILL_STOCK_COUNT_HASH.getRealKey(""),seckillId+"",seckillGoodsVo.getStockCount()+"");

            rocketMQTemplate.syncSend(MQConstants.CLEAR_STOCK_OVER_MAP_DEST,seckillId);
        }

    }





}
